package com.xposed.openfire.smack.fragment;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.xposed.openfire.smack.APPOpenfireSmack;
import com.xposed.openfire.smack.AddUserActivity;
import com.xposed.openfire.smack.ChatMessageActivity;
import com.xposed.openfire.smack.Constants;
import com.xposed.openfire.smack.R;
import com.xposed.openfire.smack.adapter.UserListAdapter;
import com.xposed.openfire.smack.entity.FriendGood;
import com.xposed.openfire.smack.entity.FriendGoodDao;
import com.xposed.openfire.smack.xmpp.XmppConnection;

import org.greenrobot.greendao.query.QueryBuilder;
import org.jivesoftware.smack.roster.RosterEntry;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;

public class FriendFragment extends Fragment implements UserListAdapter.OnItemClickListener {

    Unbinder unbinder;
    @BindView(R.id.recycler_view)
    RecyclerView recyclerView;

    private UserListAdapter listAdapter;

    private List<FriendGood> friends = new ArrayList<>();

    private CompositeDisposable mDisposables = new CompositeDisposable();

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_friend, container, (false));
        unbinder = ButterKnife.bind((this), view);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        friends.addAll(APPOpenfireSmack.getDaoSession().getFriendGoodDao().loadAll());

        listAdapter = new UserListAdapter(getActivity(), friends);
        listAdapter.setOnItemClickListener(this);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setAdapter(listAdapter);

        mDisposables.add(disposableGoodFriend(observableGoodFriend()));
    }

    @Override
    public void onItemClick(View view, int position) {
        Intent intent = new Intent(getActivity(), ChatMessageActivity.class);
        intent.putExtra(Constants.BUNDLE_KEY_USER_NAME, friends.get(position).getName());
        startActivity(intent);
    }

    @OnClick({R.id.lly_new_friend})
    public void onViewClicked(View view) {
        Intent intent = new Intent(getActivity(), AddUserActivity.class);
        startActivity(intent);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mDisposables.clear();
    }

    private Observable<FriendGood> observableGoodFriend() {
        return Observable.fromIterable(XmppConnection.getInstance().getAllEntries())
                .subscribeOn(Schedulers.io())
                .filter(new Predicate<RosterEntry>() {
                    @Override
                    public boolean test(RosterEntry rosterEntry) throws Exception {
                        QueryBuilder<FriendGood> builder = APPOpenfireSmack.getDaoSession().getFriendGoodDao().queryBuilder()
                                .where(FriendGoodDao.Properties.Name.eq(rosterEntry.getName()));
                        return builder.unique() == null;
                    }
                })
                .map(new Function<RosterEntry, FriendGood>() {
                    @Override
                    public FriendGood apply(RosterEntry rosterEntry) throws Exception {
                        FriendGood friend = new FriendGood();
                        friend.setName(rosterEntry.getName());
                        friend.setSub(rosterEntry.getType().toString());
                        friend.setJid(rosterEntry.getJid().toString());
                        return friend;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread());
    }

    private Disposable disposableGoodFriend(Observable<FriendGood> observable) {
        return observable.subscribe(new Consumer<FriendGood>() {
            @Override
            public void accept(FriendGood friend) throws Exception {
                APPOpenfireSmack.getDaoSession().getFriendGoodDao().insert(friend);
                listAdapter.addItem(friend);
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                Toast.makeText(APPOpenfireSmack.getContext(), throwable.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

}
